package com.xiguaji.tiktok.v1.ins.rank.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.xiguaji.boot.toolkit.HttpUtil;
import com.xiguaji.boot.toolkit.jdbc.Page;
import com.xiguaji.tiktok.config.exception.ParamsException;
import com.xiguaji.tiktok.utils.Ret;
import com.xiguaji.tiktok.v1.InsBaseController;
import com.xiguaji.tiktok.v1.ins.rank.dto.BrandRankDto;
import com.xiguaji.tiktok.v1.ins.rank.dto.InsRkSearch;
import com.xiguaji.tiktok.v1.ins.rank.dto.ProductRankDto;
import com.xiguaji.tiktok.v1.ins.rank.dto.RankDto;
import com.xiguaji.tiktok.v1.ins.rank.service.InsRankService;
import com.xiguaji.tiktok.v1.product.service.ProductService;
import com.xiguaji.tiktok.v1.tiktok.permission.Limit;
import com.xiguaji.tiktok.v1.tiktok.permission.RequestLimit;
import com.xiguaji.tiktok.v1.user.log.Operation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.*;

import static org.apache.commons.codec.CharEncoding.UTF_8;

@RestController
@Api(value = "ins排行榜",tags = {"ins排行榜"})
public class InsRankController extends InsBaseController {

    @Autowired
    InsRankService insRankService;

    @Autowired
    ProductService productPerService;

    @ApiOperation(value = "获取INS粉丝排行列表")
    @RequestMapping(value = "fl/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "InsFollowerRankLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation(value = "获取INS粉丝排行列表")
    public String getFollowerRankPage(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));

        if(search.getDate() < 1){
            search.setDate(insRankService.getUpdateDateCodeByFollowerRank(search.getCategoryName(),search.getNation()));
        }
        return Ret.success("success",insRankService.getFollowerRankPage(search));
    }

    @ApiOperation(value = "导出INS粉丝排行列表")
    @RequestMapping(value = "fl/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出INS粉丝排行列表")
    public void exportFollowerRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));

        if(search.getDate() < 1){
            search.setDate(insRankService.getUpdateDateCodeByFollowerRank(search.getCategoryName(),search.getNation()));
        }
        val followerRankList = insRankService.getFollowerRankList(search);
        String [] columns = new String[]{"Username","Nickname","Primary Category","Secondary Category","Followers","Follower Growth","Avg Likes","Avg ER"};
        List<Map<String,Object>> rows = new ArrayList<>();

        followerRankList.forEach( f ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],f.getUsername());
            row.put(columns[1],f.getFullName());
            row.put(columns[2],f.getCategoryName());
            row.put(columns[3],f.getSecondCategory());
            row.put(columns[4],f.getFollowerCount());
            row.put(columns[5],f.getFollowerGrow());
            row.put(columns[6],f.getAvgLike());
            row.put(columns[7],f.getAvgEr());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();

    }

    @ApiOperation(value = "获取博主涨粉榜时间日期")
    @RequestMapping(value = "fg/date",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getRankingDate(){
        // String category = getParam(String.class, URLDecoder.decode(data,"UTF-8"),"category");
        return Ret.success("OK",insRankService.getRankingDate(""));
    }

    @ApiOperation(value = "获取INS粉丝增长排行列表")
    @RequestMapping(value = "fg/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "InsFollowerRankLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation(value = "获取INS粉丝增长排行列表")
    public String getFgRankPage(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Page<RankDto> rankDtoPage;
        switch (search.getRankType()){
            case 2:
                rankDtoPage = insRankService.getFgWeekRankPage(search);
                break;
            case 3:
                rankDtoPage = insRankService.getFgMonthRankPage(search);
                break;
            default:
                rankDtoPage = insRankService.getFgDayRankPage(search);
                break;

        }
        return Ret.success("success",rankDtoPage);
    }


    @ApiOperation(value = "导出INS粉丝增长排行列表")
    @RequestMapping(value = "fg/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出INS粉丝增长排行列表")
    public void exportFgRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        if(search.getDate() < 1){
            search.setDate(insRankService.getUpdateDateCodeByFollowerRank(search.getCategoryName(),search.getNation()));
        }
        List<RankDto> followerRankList;

        int dataSize = productPerService.getPermissionNumber(getRoleId(),"InsFollowerRankLimit");

        switch (search.getRankType()){
            case 2:
                followerRankList = insRankService.getFgMonthRankList(search,dataSize);
                break;
            case 3:
                followerRankList = insRankService.getFgWeekRankList(search,dataSize);
                break;
            default:
                followerRankList = insRankService.getFgDayRankList(search,dataSize);
                break;

        }

        String [] columns = new String[]{"Username","Nickname","Primary Category","Secondary Category","Followers","Follower Growth"};
        List<Map<String,Object>> rows = new ArrayList<>();

        followerRankList.forEach( f ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],f.getUsername());
            row.put(columns[1],f.getFullName());
            row.put(columns[2],f.getCategoryName());
            row.put(columns[3],f.getSecondCategory());
            row.put(columns[4],f.getFollowerCount());
            row.put(columns[5],f.getFollowerGrow());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();

    }

    @ApiOperation(value = "获取博主排行榜更新时间")
    @RequestMapping(value = "fg/update",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getRankingUpdate(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Map<String,Long> result = new HashMap<>();
        result.put("daily",insRankService.getUpdateTimeByFgDayRank(search.getCategoryName()));
        result.put("weekly",insRankService.getUpdateTimeByFgWeekRank(search.getCategoryName()));
        result.put("monthly",insRankService.getUpdateTimeByFgMonthRank(search.getCategoryName()));
        return Ret.success("OK",result);
    }

    /**
     *
     * @param data
     * @return
     * @throws UnsupportedEncodingException
     * @throws ParamsException
     */
    @ApiOperation(value = "获取企业合作者排行列表")
    @RequestMapping(value = "adec/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "InsFollowerRankLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation(value = "获取企业合作者排行列表")
    public String getAdecRankPage(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Page<RankDto> rankDtoPage;
        if(search.getRankType() == 3){
            rankDtoPage = insRankService.getAdecMonthRankPage(search);
        }else{
            rankDtoPage = insRankService.getAdecWeekRankPage(search);
        }
        return Ret.success("success",rankDtoPage);
    }

    /**
     *
     * @param data
     * @return
     * @throws UnsupportedEncodingException
     * @throws ParamsException
     */
    @ApiOperation(value = "获取企业合作者榜更新时间")
    @RequestMapping(value = "adec/update",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getAdecRankingUpdate(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Map<String,Long> result = new HashMap<>(2);
        result.put("weekly",insRankService.getUpdateTimeByAdecWeekRank(search.getCategoryName()));
        result.put("monthly",insRankService.getUpdateTimeByAdecMonthRank(search.getCategoryName()));
        return Ret.success("OK",result);
    }

    /**
     *
     * @return
     */
    @ApiOperation(value = "获取企业合作者榜时间日期")
    @RequestMapping(value = "adec/date",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getAdecRankingDate(){
        return Ret.success("OK",insRankService.getAdecRankingDate(""));
    }

    /**
     *
     * @param data
     * @throws IOException
     * @throws ParamsException
     */
    @ApiOperation(value = "导出企业合作者榜排行列表")
    @RequestMapping(value = "adec/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出企业合作者榜排行列表")
    public void exportAdecRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        if(search.getDate() < 1){
            search.setDate(insRankService.getMaxDateCodeByAdecWeekRank(search.getCategoryName()));
        }
        List<RankDto> followerRankList;
        int dataSize = productPerService.getPermissionNumber(getRoleId(),"InsFollowerRankLimit");

        if(search.getRankType() == 3){
            followerRankList = insRankService.getAdecMonthRankList(search,dataSize);
        }else{
            followerRankList = insRankService.getAdecWeekRankList(search,dataSize);
        }

        String [] columns = new String[]{"Username","Nickname","Primary Category","Secondary Category","Followers","Ads Posts","Engagements"};
        List<Map<String,Object>> rows = new ArrayList<>();

        followerRankList.forEach( f ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],f.getUsername());
            row.put(columns[1],f.getFullName());
            row.put(columns[2],f.getCategoryName());
            row.put(columns[3],f.getSecondCategory());
            row.put(columns[4],f.getFollowerCount());
            row.put(columns[5],f.getAdCount());
            row.put(columns[6],f.getAdTec());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();

    }

    @ApiOperation("ins商品排行榜")
    @RequestMapping(value = "product/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "ProductPageLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation("ins商品排行榜")
    public String getProductRank(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch insRkSearch = getParam(InsRkSearch.class, URLDecoder.decode(data,UTF_8));
        return Ret.success("SUCCESS!",insRankService.getProductRankPage(insRkSearch));
    }

    @ApiOperation(value = "导出INS商品排行榜")
    @RequestMapping(value = "product/rank/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出INS商品排行榜")
    public void exportProductRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        if(search.getDate() < 1){
            search.setDate(insRankService.getProductNewestDateCode(search));
        }
        int dataSize = productPerService.getPermissionNumber(getRoleId(),"ProductPageLimit");

        List<ProductRankDto> followerRankList = insRankService.getProductRankList(search,dataSize);

        String [] columns = new String[]{"Username","Nickname","ProductName","Category","Price","Influencer","Post","Engagements"};
        List<Map<String,Object>> rows = new ArrayList<>();

        followerRankList.forEach( f ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],f.getUsername());
            row.put(columns[1],f.getFullName());
            row.put(columns[2],f.getProductName());
            row.put(columns[3],f.getOverallCategoryName());
            row.put(columns[4],f.getPrice());
            row.put(columns[5],f.getInfluencerCount());
            row.put(columns[6],f.getMediaCount());
            row.put(columns[7],f.getTec());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();
    }

    @ApiOperation(value = "获取INS商品排行榜时间列表")
    @RequestMapping(value = "product/rank/dates",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getProductRankDateCodes() throws UnsupportedEncodingException, ParamsException {
        return Ret.success("OK",insRankService.getProductRankDate());
    }



    //####品牌#####
    @ApiOperation(value = "获取品牌排行列表")
    @RequestMapping(value = "brand/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "InsBrandRankLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation(value = "获取品牌排行列表")
    public String getBrandRankPage(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Page<BrandRankDto> rankDtoPage;
        switch (search.getRankType()){
            case 1:
                rankDtoPage = insRankService.getBrandWeekRankPage(search);
                break;
            case 2:
                rankDtoPage = insRankService.getBrandMonthRankPage(search);
                break;
            default:
                rankDtoPage = insRankService.getBrandDayRankPage(search);
                break;

        }
        return Ret.success("success",rankDtoPage);
    }


    @ApiOperation(value = "导出品牌排行列表")
    @RequestMapping(value = "brand/rank/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出品牌排行列表")
    public void exportBrandRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        if(search.getDate() < 1){
            search.setDate(insRankService.getUpdateDateCodeByFollowerRank(search.getCategoryName(),search.getNation()));
        }
        List<BrandRankDto> brandRankList;

        int dataSize = productPerService.getPermissionNumber(getRoleId(),"InsBrandRankLimit");

        switch (search.getRankType()){
            case 2:
                brandRankList = insRankService.getBrandMonthRankList(search,dataSize);
                break;
            case 3:
                brandRankList = insRankService.getBrandWeekRankList(search,dataSize);
                break;
            default:
                brandRankList = insRankService.getBrandDayRankList(search,dataSize);
                break;

        }

        String [] columns = new String[]{"Brand","Category","Post","Likes","Reviews","Engagements"};
        List<Map<String,Object>> rows = new ArrayList<>();

        brandRankList.forEach( b ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],b.getEnName());
            row.put(columns[1],b.getCategoryName());
            row.put(columns[2],b.getMediaCount());
            row.put(columns[3],b.getLikeCount());
            row.put(columns[4],b.getReviewCount());
            row.put(columns[5],b.getEngagements());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();

    }

    @ApiOperation(value = "获取品牌排行榜日期列表")
    @RequestMapping(value = "brand/rank/dates",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getRankDateList(){
        // String category = getParam(String.class, URLDecoder.decode(data,"UTF-8"),"category");
        return Ret.success("OK",insRankService.getBrandRankingDate(""));
    }

    @ApiOperation(value = "获取品牌排行榜更新时间")
    @RequestMapping(value = "brand/rank/update",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getBrandUpdate(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Map<String,Long> result = new HashMap<>();
        result.put("daily",insRankService.getUpdateTimeByBrandDayRank(search.getCategoryName()));
        result.put("weekly",insRankService.getUpdateTimeByBrandWeekRank(search.getCategoryName()));
        result.put("monthly",insRankService.getUpdateTimeByBrandMonthRank(search.getCategoryName()));
        return Ret.success("OK",result);
    }


    //####带货达人#####
    @ApiOperation(value = "获取带货达人排行列表")
    @RequestMapping(value = "blogger/bgs/rank",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @RequestLimit(value = "InsFollowerRankLimit",property = "page,pageSize",validateType = Limit.VIEW_DATA_LIMIT)
    @Operation(value = "获取带货达人排行列表")
    public String getBloggerBgsRankPage(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Page<RankDto> rankDtoPage;
        switch (search.getRankType()){
            case 1:
                rankDtoPage = insRankService.getBloggerBgsWeekRankPage(search);
                break;
            case 2:
                rankDtoPage = insRankService.getBloggerBgsMonthRankPage(search);
                break;
            default:
                rankDtoPage = insRankService.getBloggerBgsDayRankPage(search);
                break;

        }
        return Ret.success("success",rankDtoPage);
    }


    @ApiOperation(value = "导出带货达人排行列表")
    @RequestMapping(value = "blogger/bgs/rank/export",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    @Operation(value = "导出带货达人排行列表")
    public void exportBloggerBgsRank(String data) throws IOException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        if(search.getDate() < 1){
            search.setDate(insRankService.getBloggerBgsNewestDateCode(search));
        }
        List<RankDto> bloggerRankList;

        int dataSize = productPerService.getPermissionNumber(getRoleId(),"InsFollowerRankLimit");

        switch (search.getRankType()){
            case 2:
                bloggerRankList = insRankService.getBloggerBgsMonthRankList(search,dataSize);
                break;
            case 3:
                bloggerRankList = insRankService.getBloggerBgsWeekRankList(search,dataSize);
                break;
            default:
                bloggerRankList = insRankService.getBloggerBgsDayRankList(search,dataSize);
                break;

        }

        String [] columns = new String[]{"Username","Nickname","Primary Category","Secondary Category","Followers","Posts","Engagements"};
        List<Map<String,Object>> rows = new ArrayList<>();

        bloggerRankList.forEach( f ->{
            Map<String,Object> row = new LinkedHashMap<>();
            row.put(columns[0],f.getUsername());
            row.put(columns[1],f.getFullName());
            row.put(columns[2],f.getCategoryName());
            row.put(columns[3],f.getSecondCategory());
            row.put(columns[4],f.getFollowerCount());
            row.put(columns[5],f.getMediaCount());
            row.put(columns[6],f.getEngagements());
            rows.add(row);
        });
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(rows,true);
        HttpUtil.getResponse().setContentType("application/vnd.ms-excel;charset=utf-8");
        HttpUtil.getResponse().setHeader("Content-Disposition","attachment;filename="+Integer.parseInt(DateUtil.format(LocalDateTime.now(),"yyyyMMdd"))+".xls");
        writer.flush(HttpUtil.getResponse().getOutputStream());
        writer.close();

    }

    @ApiOperation(value = "获取带货达人排行榜日期列表")
    @RequestMapping(value = "blogger/bgs/rank/dates",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getBloggerBgsRankDateList(){
        // String category = getParam(String.class, URLDecoder.decode(data,"UTF-8"),"category");
        return Ret.success("OK",insRankService.getBloggerBgsRankingDate(""));
    }

    @ApiOperation(value = "获取带货达人排行榜更新时间")
    @RequestMapping(value = "blogger/bgs/rank/update",method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public String getBloggerBgsUpdate(String data) throws UnsupportedEncodingException, ParamsException {
        InsRkSearch search = getParam(InsRkSearch.class, URLDecoder.decode(data,"UTF-8"));
        Map<String,Long> result = new HashMap<>();
        result.put("daily",insRankService.getUpdateTimeByBloggerBgsDayRank(search.getCategoryName()));
        result.put("weekly",insRankService.getUpdateTimeByBloggerBgsWeekRank(search.getCategoryName()));
        result.put("monthly",insRankService.getUpdateTimeByBloggerBgsMonthRank(search.getCategoryName()));
        return Ret.success("OK",result);
    }
}
